package bud.mobile.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import lombok.extern.slf4j.Slf4j;

import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import bud.mobile.service.IMobileMemberService;
import bud.mobile.service.IMobileMemberService.MemberResult;
import bud.vo.CommentMemberDTO;
import bud.vo.CommentShopDTO;
import bud.vo.FriendDTO;
import bud.vo.LocationDTO;
import bud.vo.MemberDTO;
import bud.vo.ShopDTO;

@Controller
@Slf4j
public class ScanController {
	@Inject
	private IMobileMemberService service;
	public IMobileMemberService getService() {
		return service;
	}
	public void setService(IMobileMemberService service) {
		this.service = service;
	}
	
	@RequestMapping("scan/scanMap")
	public String scanMap(Model model, HttpServletRequest request){
		ObjectMapper om = new ObjectMapper();
		HttpSession session = request.getSession();
		MemberDTO member = (MemberDTO)session.getAttribute("memberSession");
		try {
			if (member.getMem_scaninfo().equals("s")){
				String shopList = om.writeValueAsString(service.getShopList());
				model.addAttribute("JsonListShop", shopList);
			} else if (member.getMem_scaninfo().equals("p")){
				Map<Integer, LocationDTO> userLocation = (Map<Integer, LocationDTO>) request.getSession().getServletContext().getAttribute("userLocation");
				Map<Integer, LocationDTO> userLocationNew = new HashMap<Integer, LocationDTO>(userLocation);
				List<MemberDTO> friendList = member.getFriendList();
				userLocationNew.remove(member.getMem_no());
				for (int i=0; i<friendList.size(); i++){
					userLocationNew.remove(friendList.get(i).getMem_no());
				}
				List<LocationDTO> userList = new ArrayList<>(userLocationNew.values());
				String peopleList = om.writeValueAsString(userList);
				model.addAttribute("JsonList", peopleList);
				
			} else if ((member.getMem_scaninfo().equals("f"))){
				Map<Integer, LocationDTO> userLocation = (Map<Integer, LocationDTO>) request.getSession().getServletContext().getAttribute("userLocation");
				List<LocationDTO> friendLocationList = new ArrayList<>();
				List<MemberDTO> friendList = member.getFriendList();
				for (int i=0; i<friendList.size(); i++){
					if(userLocation.get(friendList.get(i).getMem_no()) != null){
						friendLocationList.add(userLocation.get(friendList.get(i).getMem_no()));
					}
				}
				String friendListJson = om.writeValueAsString(friendLocationList);
				model.addAttribute("JsonList", friendListJson);	
			}
		} catch (IOException e) {
			throw new RuntimeException();
		}
		
		return "scan/scanMap";
	}
	
	@RequestMapping("/scan/scanMapReset")
	public String scanMapReset(MemberDTO member, @RequestParam("range")int range,
			Model model, HttpServletRequest request){
		MemberDTO tempMember = service.getMember(member.getMem_no());
		ObjectMapper om = new ObjectMapper();
		try {
			if (member.getMem_scaninfo().equals("s")){
				String shopList = om.writeValueAsString(service.getShopList());
				model.addAttribute("JsonListShop", shopList);				
			} else if (member.getMem_scaninfo().equals("p")){
				Map<Integer, LocationDTO> userLocation = (Map<Integer, LocationDTO>) request.getSession().getServletContext().getAttribute("userLocation");
				Map<Integer, LocationDTO> userLocationNew = new HashMap<Integer, LocationDTO>(userLocation);
				List<MemberDTO> friendList = tempMember.getFriendList();
				
				userLocationNew.remove(tempMember.getMem_no());
				for (int i=0; i<friendList.size(); i++){
					userLocationNew.remove(friendList.get(i).getMem_no());
				}
				List<LocationDTO> userList = new ArrayList<>(userLocationNew.values());
				String peopleList = om.writeValueAsString(userList);
				model.addAttribute("JsonList", peopleList);			
			} else if ((member.getMem_scaninfo().equals("f"))){
				Map<Integer, LocationDTO> userLocation = (Map<Integer, LocationDTO>) request.getSession().getServletContext().getAttribute("userLocation");
				List<LocationDTO> friendLocationList = new ArrayList<>();
				List<MemberDTO> friendList = tempMember.getFriendList();
				for (int i=0; i<friendList.size(); i++){
					if(userLocation.get(friendList.get(i).getMem_no()) != null){
						friendLocationList.add(userLocation.get(friendList.get(i).getMem_no()));
					}
				}
				String friendListJson = om.writeValueAsString(friendLocationList);
				model.addAttribute("JsonList", friendListJson);	
			}
		} catch (IOException e) {
			throw new RuntimeException();
		}
		if(member.getMem_scaninfo() != null){
			service.updateMember(member);
			HttpSession session = request.getSession();
			tempMember = service.getMember(member.getMem_no());
			session.setAttribute("memberSession", tempMember);
		}
		model.addAttribute("range", range);
		return "scan/scanMap";
	}
	
	@RequestMapping("scan/scanMapLocSet")
	public String scanMapLocSet(@RequestParam("lat") double lat, @RequestParam("lng") double lng, 
			HttpServletRequest request){
		HttpSession session  = request.getSession();
		Map<Integer, LocationDTO> userLocation = (Map<Integer, LocationDTO>) request.getSession().getServletContext().getAttribute("userLocation");
		MemberDTO member = (MemberDTO)session.getAttribute("memberSession"); 
		
		LocationDTO location = new LocationDTO();
    	location.setLo_ref_mem(member.getMem_no());
    	location.setLo_latitude(lat);
    	location.setLo_longitude(lng);
    	location.setLo_sec_tofriend(member.getMem_sec_tofriend());
    	location.setLo_sec_topeople(member.getMem_sec_topeople());
    	location.setLo_photo(member.getMem_photoStr());
    	userLocation.remove(member.getMem_no());
    	userLocation.put(member.getMem_no(), location);
		return "jsonView";
	} 
	
	@RequestMapping("scan/scanList")
	public String scanList(double lat, double lng, int range, HttpServletRequest request, Model model){
		HttpSession session = request.getSession();
		MemberDTO member = (MemberDTO)session.getAttribute("memberSession");
		if (member.getMem_scaninfo().equals("s")){
			List<ShopDTO> shopList = service.getShopList();
			for (int i=0; i<shopList.size(); i++){
				ShopDTO shop = shopList.get(i);
				if (rangeCheck(shop.getSh_latitude(), shop.getSh_longitude(), lat, lng, range)){
					shopList.remove(i);
				}
			}
			model.addAttribute("scanList", shopList);
		} else {
			Map<Integer, LocationDTO> userLocation = (Map<Integer, LocationDTO>) request.getSession().getServletContext().getAttribute("userLocation");
			List<LocationDTO> locationList = new ArrayList<>(userLocation.values());
			List<MemberDTO> scanFriendList = new ArrayList<>();
			List<MemberDTO> scanPeopleList = new ArrayList<>();
			List<MemberDTO> friendList = member.getFriendList();
			for (int i=0; i<locationList.size(); i++){
				LocationDTO location = locationList.get(i);
				if (!location.getLo_ref_mem().equals(member.getMem_no())){
					boolean isFriend = false;
					for (int j=0; j<friendList.size(); j++){
						if (location.getLo_ref_mem().equals(friendList.get(j).getMem_no())){
							isFriend = true;
							break;
						}
					}
					if (isFriend){
						scanFriendList.add(service.getMember(locationList.get(i).getLo_ref_mem()));
					} else {
						scanPeopleList.add(service.getMember(locationList.get(i).getLo_ref_mem()));
					}
				}
			}
			if (member.getMem_scaninfo().equals("f")){
				model.addAttribute("scanList", scanFriendList);
			} else {
				model.addAttribute("scanList", scanPeopleList);
			}
		}
		model.addAttribute("range", range);
		return "scan/scanList";
	} 
	
	@RequestMapping("scan/scanProfileShop")
	public String scanProfileShop(int sh_no, Model model){
		ShopDTO shop = service.getShop(sh_no);
		model.addAttribute("shop", shop);
		model.addAttribute("commentShopList",service.getCommentShop(sh_no));
		return "scan/scanProfileShop";
	} 
	
	@RequestMapping("scan/scanProfileBud")
	public String scanProfileBud(int mem_no, Model model){
		MemberDTO member = service.getMember(mem_no);
		model.addAttribute("member", member);
		model.addAttribute("commentMemberList",service.getCommentMember(mem_no));
		return "scan/scanProfileBud";
	} 
	
	@RequestMapping("scan/scanProfilePeople")
	public String scanProfilePeople(int mem_no, Model model){
		MemberDTO member = service.getMember(mem_no);
		model.addAttribute("member", member);
		model.addAttribute("commentMemberList",service.getCommentMember(mem_no));
		return "scan/scanProfilePeople";
	}
	
	@RequestMapping("scan/shopCommentAdd")
	public String shopCommentAdd(CommentShopDTO commentShop, Model model){
		ShopDTO shop = service.getShop(commentShop.getCs_ref_key());
		model.addAttribute("shop", shop);
		service.insertCommentShop(commentShop);
		model.addAttribute("commentShopList",service.getCommentShop(commentShop.getCs_ref_key()));
		return "jsonView";
	} 

	@RequestMapping("scan/memberCommentAdd")
	public String memberCommentAdd(CommentMemberDTO commentMember, Model model){
		MemberDTO member = service.getMember(commentMember.getCm_ref_key());
		model.addAttribute("member", member);
		service.insertCommentMember(commentMember);
		model.addAttribute("commentMemberList",service.getCommentMember(commentMember.getCm_ref_key()));
		return "jsonView";
	}
	
	@RequestMapping("scan/scanMapRequestBud")
	public String scanMapRequestBud(int mem_no, Model model, HttpServletRequest request){
		HttpSession session = request.getSession();
		MemberDTO memberMe = (MemberDTO)session.getAttribute("memberSession");
		MemberDTO memberFriend = service.getMember(mem_no);
		
		FriendDTO friend = new FriendDTO();
		friend.setFr_member(memberMe.getMem_no());
		friend.setFr_friend(memberFriend.getMem_no());
		if (service.getIsRequestFriend(friend)){
			return "redirect:/bud/budReceiveRequest.mo?already=true";
		}
		
		friend.setFr_member(memberFriend.getMem_no());
		friend.setFr_friend(memberMe.getMem_no());
		friend.setFr_request("r");
		MemberResult result = service.insertFriend(friend);
		String msg = null;
		if (result == MemberResult.OK){
			msg = memberFriend.getMem_name() + "님에게 벗 요청!!";
		} else {
			msg = "이미 등록된 친구이거나 상대방의 수락을 기다리는 중입니다.";
		}
		
		model.addAttribute("msg", msg);
		model.addAttribute("member", memberFriend);
		model.addAttribute("commentMemberList",service.getCommentMember(mem_no));
		return "scan/scanProfilePeople";
	}
	
	public boolean rangeCheck(double lat1, double lng1, double lat2, double lng2, int range){
			
        double EARTH_R, Rad, radLat1, radLat2, radDist; 
        double distance, ret;

        EARTH_R = 6371000.0;
        Rad = Math.PI/180;
        radLat1 = Rad * lat1;
        radLat2 = Rad * lat2;
        radDist = Rad * (lng1 - lng2);
       
        distance = Math.sin(radLat1) * Math.sin(radLat2);
        distance = distance + Math.cos(radLat1) * Math.cos(radLat2) * Math.cos(radDist);
        ret = EARTH_R * Math.acos(distance);
        int rtn = Math.round(Math.round(ret) / 1000);
        
        if (rtn < range){
        	return false;
        }
    	return true;
	}
	
}
